#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "rngs.h"
#include "testhelpers.c"
#include <math.h>

// Unit Test for shuffle

int main(){
    int player;
    struct gameState *state = malloc(sizeof(struct gameState));
    float averagePos;
    int countPos;
    int testDeckSize;
    int numTests = 50;

    int i;
    int j;
    int k;

    resetFlag();

    // Sets state for testing
    setState(state);
    resetDeck(state);

    printf("Testing shuffle\n");

    // Testing error condition for bad player number
    player = -1;
    if(shuffle(player, state) != -1){
        printf("Shuffle passed when in a bad state, should have failed(player -1)\n");
        incState();
    }
    player = 10;
    if(shuffle(player, state) == -1){
        printf("Shuffle passed when in a bad state, should have failed(player10)\n");
        incState();
    }
    player = 0; // resets player to good player number

    // testing typical use
    resetDeck(state);

    if(shuffle(player, state) != 0){
        printf("Shuffle failed when player number should be good.");
        incState();
    }
    if(state->deckCount[player] != 10)
        assertMessage("Deck Count should be %d but it is %d\n", 10, state->deckCount[player]);

    //random testing
    resetDeck(state);

    for (k = 0; k < numTests; k++){
        free(state);
        state = malloc(sizeof(struct gameState));
        setState(state);
        resetDeck(state);

        testDeckSize = floor(Random() * 490);
        for (i = 0; i < 2; i++){
            for (j = 0; j < testDeckSize; j++){
                  state->deck[i][j+10] = randomCard(state);
                  state->deckCount[i]++;
            }
        }
            if(shuffle(0, state) != 0){
                printf("Failure on shuffle when shuffle should be in a good state\n");
                incState();
            }
            if(shuffle(1, state) != 0){
                printf("Failure on shuffle when shuffle should be in a good state\n");
                incState();
            }
            if(state->deckCount[0] != testDeckSize + 10)
                assertMessage("Deck Count is %d but it should be %d\n", testDeckSize+10, state->deckCount[0]);
            if(state->deckCount[1] != testDeckSize + 10)
                assertMessage("Deck Count is %d but it should be %d\n", testDeckSize+10, state->deckCount[0]);
    }
        free(state);
        state = malloc(sizeof(struct gameState));
        setState(state);

        // this test will determine whether the shuffle randomizes or not.
        countPos = 0;
        for (i = 0; i < numTests; i++){
            resetDeck(state);
            shuffle(player, state);
            for (j = 0; j < state->deckCount[player]; j++){
                if (state->deck[player][j] == estate){
                    countPos += j;
                    break;
                }
            }
        }
        //printf("position: %d test: %d\n", countPos, numTests);
        averagePos = (float)countPos/(float)numTests;
        //printf("Average location of first estate: %f\n", averagePos);
        if (!(floor(averagePos) < averagePos)){
            printf("The average position of the first estate is an integer.  This could indicate this function is not randomizing properly, or you are not running enough test cases\n");
            incState();
        }

    if(testState() == 0)
        printf("Shuffle Test Passed\n");
    else
        printf("Shuffle Test Failed\n");

    free(state);
    return 0;
}
